package com.yami.trading.service.impl;

import com.mysql.cj.util.StringUtils;
import com.yami.trading.bean.log.domain.CodeLog;
import com.yami.trading.common.manager.BlacklistIpTimeWindow;
import com.yami.trading.common.manager.SendCountTimeWindow;
import com.yami.trading.service.EmailSendService;
import com.yami.trading.service.IdentifyingCodeService;
import com.yami.trading.service.IdentifyingCodeTimeWindowService;
import com.yami.trading.service.SmsSendService;
import com.yami.trading.service.syspara.SysparaService;
import com.yami.trading.service.system.CodeLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
import java.util.Date;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class IdentifyingCodeServiceImpl  implements IdentifyingCodeService {



    private Logger logger = LoggerFactory.getLogger(IdentifyingCodeServiceImpl.class);

    @Autowired
    private SmsSendService smsSendService;
    @Autowired
    private EmailSendService  emailSendService;

    @Autowired
    private IdentifyingCodeTimeWindowService identifyingCodeTimeWindowService;

    @Autowired
    private SendCountTimeWindow sendCountTimeWindow;


    @Autowired
    private BlacklistIpTimeWindow blacklistIpTimeWindow;

    @Autowired
    private SysparaService sysparaService;

    @Autowired
    private CodeLogService codeLogService;

    private Map<String, Integer> ipCache = new ConcurrentHashMap<String, Integer>();

    @Override
    public void send(String target, String ip) {
        String code = null;
        if (chcekIp(ip)) {// 被封的ip直接返回 不操作
            return;
        }
        /**
         * 短信发送签名
         */
//		String smsbao_sign = sysparaService.find("smsbao_sign").getValue();

        // 短信发送文本[TEST]code is ：{0}
        String send_code_text = this.sysparaService.find("send_code_text").getSvalue();
        if (StringUtils.isNullOrEmpty(send_code_text)) {
            logger.error("send_code_text 未配置");
            return;
        }

        /**
         * 是否每次发送的code都不一样
         */
        boolean send_code_always_new = this.sysparaService.find("send_code_always_new").getBoolean();

        Object object = this.identifyingCodeTimeWindowService.getAuthCode(target);
        if (object == null || send_code_always_new) {
            Random random = new Random();
            code = String.valueOf(random.nextInt(999999) % 900000 + 100000);
        } else {
            code = String.valueOf(object);
        }
//		log.info(MessageFormat.format("target:{0},code:{1},ip:{2}", target, code, ip));

        String content = MessageFormat.format("code is ：{0}", new Object[] { code });
        if (target.indexOf("@") == -1) {

            /**
             * 发送的短信接口类型 tiantian---天天---smsSendService--->>>>--
             * moduyun---摩杜云---smsSingleSender
             */
            String send_code_type = this.sysparaService.find("send_code_type").getSvalue();
            if (StringUtils.isNullOrEmpty(send_code_type)) {
                logger.error("send_code_type 未配置");
                return;
            }

            if ("tiantian".equals(send_code_type)) {
                smsSendService.send(target, MessageFormat.format(send_code_text, new Object[] { code }));
                logger.info(MessageFormat.format("tiangtian--target:{0},code:{1},ip:{2}", target, code, ip));
            }

//			else if ("moduyun".equals(send_code_type)) {
//				// -- 摩杜云短信签名的Id--accesskey,secretkey,signId,templateId
//				String send_code_moduyun = this.sysparaService.find("send_code_moduyun").getValue();
//				String[] send_code_moduyun_parts = send_code_moduyun.split(",");
//				List<String> params = new ArrayList<String>();
//				params.add(code);
//				String strh_code = "";
//				strh_code = target.substring(0, 2);
//				if ("86".equals(strh_code)) {
//					try {
//						smsSingleSender.send(0, "86", target.substring(2, target.length()), send_code_moduyun_parts[2],
//								send_code_moduyun_parts[3], params, "", send_code_moduyun_parts[0],
//								send_code_moduyun_parts[1]);
//						log.info(MessageFormat.format("moduyun--target:{0},code:{1},ip:{2}", target, code, ip));
//					} catch (Exception e) {
//					}
//				}
//			}
            else if ("smsbao".equals(send_code_type)) {
                smsSendService.send(target, MessageFormat.format(send_code_text, new Object[] { code }));
                logger.info(MessageFormat.format("smsbao--target:{0},code:{1},ip:{2}", target, code, ip));
            }

        } else {
            /**
             * 邮件
             */
            emailSendService.sendEmail(target, MessageFormat.format(send_code_text, new Object[] { code }), content);
            logger.info(MessageFormat.format("email--target:{0},code:{1},ip:{2}", target, code, ip));
        }

        this.identifyingCodeTimeWindowService.putAuthCode(target, code);
        System.out.println("获取验证码：" + target + "---" + code);
        CodeLog codeLog = new CodeLog();
        codeLog.setTarget(target);
        codeLog.setLog("发送地址：" + target + ",验证码：" + code + ",ip地址：" + ip);
        codeLog.setCreateTime(new Date());
        codeLogService.save(codeLog);
    }

    /**
     * 返回true:ip已被封， false：ip正常
     *
     * @param ip
     * @return
     */
    private boolean chcekIp(String ip) {
        String check_send_count = sysparaService.find("send_code_check_ip").getSvalue();
        if (!"true".equals(check_send_count))
            return false;// 不为1时 未开启，直接返回false不做处理
        if (blacklistIpTimeWindow.getBlackIp(ip) != null)
            return true;// ip被封，不发送

        if (sendCountTimeWindow.getIpSend(ip) != null) {
            Integer count = ipCache.get(ip);
            count++;
            if (count >= 30) {// 从ip发送第一条开始
                blacklistIpTimeWindow.putBlackIp(ip, ip);
                ipCache.remove(ip);
                sendCountTimeWindow.delIpSend(ip);
                return true;
            } else {
                ipCache.put(ip, count++);
            }

        } else {
            ipCache.put(ip, 1);
            sendCountTimeWindow.putIpSend(ip, ip);
        }
        return false;

    }

}
